/**
 * 函数指针&结构体中的函数指针, 还未讲
 */
#include <stdio.h>

/**
 * function1: 函数指针 ，它存储着一个没有参数，返回值为int类型的函数的地址。
 * @return
 */
int (*function1)();

/**
 * func2: 一个函数名，它没有参数，返回一个指针，int *类型。
 * @return
 */
int* func2() {
    return 0;
}


void function_pointer();
int function_param(int, int (*pstudy)(int a));
void struct_function_pointer();
int study(int);
int study2(int);
void Dance_func();
int Sing_func(int);


int main() {
    //1.函数指针
    function_pointer();
    //2.函数指针作为参数
    function_param(456, &study);
    //3.结构体 中的 函数指针
    struct_function_pointer();
    return 0;
}

//1.函数指针
void function_pointer() {
    /**
     * 函数指针:
     *  作用     : 相当于抽象函数, 可以给这个函数指针赋值不同的函数实现, 完成不同的功能.
     *  paastudy: 函数指针的名称, 它存储着函数的地址。
     *  int a   : 调用 paastudy 的时候, 要传入一个int参数
     *  study   : 函数名, 给 paastudy 赋值
     *
     *  (int a) 可写成: (int)
     *  study   可写成: &study
     */
    int (*paastudy)(int a) = study;
    printf("1.函数指针\n");
    int v1 = (*paastudy)(9);      //调用方式一：函数指针
    int v2 = paastudy(123);       //调用方式二：函数指示符.  根据指针名称, 传参&调用方法

    paastudy = study2;            //重新赋值不同的函数(相当于 Java 的多态)
    int v3 = paastudy(11);
    printf("v1 = %d, v2 = %d, v3 = %d\n", v1, v2, v3);   //9, 123, 121
}
int study(int a) {
    printf("study: a = %d\n", a);
    return a;
}
int study2(int a) {
    printf("这是study2: a = %d\n", a);
    return a * a;
}


/**
 * 2.函数指针作为参数
 * @param a        计算得值
 * @param pbbstudy 函数指针
 * @return         计算结果
 */
int function_param(int a, int (*pbbstudy)(int a)) {
    printf("2.函数指针作为参数\n");
    int value = pbbstudy(a);
    return value;
}

//3.结构体 中的 函数指针
typedef struct {
    int age;
    void (*dance)();                //函数指针
//    void (*dance)() = Dance_func; //不能直接赋值
    int (*sing)(int i);
//    int * sing (int i);           //格式错误, 无法通过编译
} Person;
void struct_function_pointer() {
    Person person;
    person.age = 23;
    person.dance = Dance_func;  //给函数指针赋值
    person.sing = Sing_func;
    printf("3.结构体 中的 函数指针\n");
    person.dance();             //调用函数指针
    int v1 = person.sing(5);
    printf("person.sing(5)的返回值 = %d\n", v1);
}
void Dance_func() {
    printf("Xiao Ming is dancing!\n");
}
int Sing_func(int i) {
    printf("Xiao Ming Sang %d Songs.\n", i);
    return i;
}


